import { BaseScraper, type ScrapingResult } from './BaseScraper.js';
import { DataConverter, type ComponentData } from './DataConverter.js';
import type { CheerioAPI } from 'cheerio';

/**
 * Pro Components 组件数据收集器
 */
export class ProComponentsScraper extends BaseScraper {
  private readonly proComponentsUrl = 'https://procomponents.ant.design';
  private readonly githubApiUrl = 'https://api.github.com/repos/ant-design/pro-components';

  // Pro Components 组件映射
  private readonly proComponents = new Map([
    // 布局组件
    ['ProLayout', '布局'],
    ['ProCard', '布局'],
    ['ProConfigProvider', '布局'],
    
    // 数据录入
    ['ProForm', '数据录入'],
    ['BetaSchemaForm', '数据录入'],
    ['ProFormFields', '数据录入'],
    ['ProFormList', '数据录入'],
    ['ProFormDependency', '数据录入'],
    
    // 数据展示
    ['ProTable', '数据展示'],
    ['ProList', '数据展示'],
    ['ProDescriptions', '数据展示'],
    ['EditableProTable', '数据展示'],
    ['DragSortTable', '数据展示'],
    
    // 通用
    ['ProField', '通用'],
    ['ProSkeleton', '通用'],
    ['ProProvider', '通用'],
    
    // 其他
    ['ProUtils', '工具'],
  ]);

  constructor() {
    super('ProComponentsScraper', 'https://procomponents.ant.design');
  }

  /**
   * 执行数据抓取
   */
  async scrape(): Promise<ScrapingResult> {
    const startTime = Date.now();
    const result: ScrapingResult = {
      success: false,
      count: 0,
      data: [],
      errors: [],
      timestamp: new Date(),
      duration: 0,
    };

    try {
      this.log('🚀 开始抓取 Pro Components 组件数据...');

      // 1. 获取组件列表页面
      this.emitProgress({
        stage: '获取组件列表',
        current: 0,
        total: 100,
        message: '正在访问Pro Components官网...'
      });

      const componentUrls = await this.getComponentUrls();
      this.log(`📋 发现 ${componentUrls.length} 个Pro组件`);

      // 2. 抓取每个组件的详细信息
      const components: ComponentData[] = [];
      for (let i = 0; i < componentUrls.length; i++) {
        const componentUrl = componentUrls[i];
        if (!componentUrl) continue;
        
        this.emitProgress({
          stage: '抓取组件详情',
          current: i + 1,
          total: componentUrls.length,
          item: componentUrl.name,
          message: `正在抓取 ${componentUrl.name}...`
        });

        try {
          const componentData = await this.scrapeProComponent(componentUrl);
          if (componentData) {
            components.push(componentData);
            this.log(`✅ 成功抓取Pro组件: ${componentData.name}`);
          }
        } catch (error) {
          const errorMsg = `抓取Pro组件 ${componentUrl.name} 失败: ${error instanceof Error ? error.message : String(error)}`;
          result.errors.push(errorMsg);
          this.error(errorMsg);
        }

        // 遵守速率限制
        await this.delay(this.rateLimitDelay);
      }

      // 3. 添加内置的Pro组件
      components.push(...this.createBuiltInProComponents());

      result.data = components;
      result.count = components.length;
      result.success = true;
      
      this.log(`🎉 抓取完成! 成功收集 ${components.length} 个Pro组件`);

    } catch (error) {
      const errorMsg = `抓取过程发生错误: ${error instanceof Error ? error.message : String(error)}`;
      result.errors.push(errorMsg);
      this.error(errorMsg);
    }

    result.duration = Date.now() - startTime;
    return result;
  }

  /**
   * 获取Pro Components组件URL列表
   */
  private async getComponentUrls(): Promise<Array<{ name: string; url: string; category: string }>> {
    const componentUrls: Array<{ name: string; url: string; category: string }> = [];

    try {
      const html = await this.fetchPage('/components');
      const $ = this.parseHtml(html);

      // 查找组件链接
      $('a[href*="/components/"]').each((_, element) => {
        const $link = $(element);
        const href = $link.attr('href');
        const text = this.cleanText($link.text());
        
        if (href && text && href !== '/components') {
          const componentName = this.extractComponentName(href);
          if (componentName && this.proComponents.has(componentName)) {
            const category = this.proComponents.get(componentName) || '其他';
            
            componentUrls.push({
              name: componentName,
              url: href,
              category
            });
          }
        }
      });

      // 如果网页抓取失败，使用预定义的组件列表
      if (componentUrls.length === 0) {
        for (const [name, category] of this.proComponents) {
          componentUrls.push({
            name,
            url: `/components/${name.toLowerCase().replace(/([A-Z])/g, '-$1').slice(1)}`,
            category
          });
        }
      }

    } catch (error) {
      this.warn('无法获取组件列表，使用预定义列表');
      
      // 使用预定义的组件列表
      for (const [name, category] of this.proComponents) {
        componentUrls.push({
          name,
          url: `/components/${name.toLowerCase().replace(/([A-Z])/g, '-$1').slice(1)}`,
          category
        });
      }
    }

    return Array.from(new Map(componentUrls.map(c => [c.name, c])).values());
  }

  /**
   * 抓取单个Pro组件的详细信息
   */
  private async scrapeProComponent(componentInfo: { name: string; url: string; category: string }): Promise<ComponentData | null> {
    try {
      const html = await this.fetchPage(componentInfo.url);
      const $ = this.parseHtml(html);

      // 提取组件基本信息
      const title = this.extractTitle($) || componentInfo.name;
      const description = this.extractDescription($) || DataConverter.generateDefaultDescription(componentInfo.name, componentInfo.category);
      
      // 提取API文档
      const props = this.extractProProps($);
      const examples = this.extractProExamples($, componentInfo.name);
      const imports = this.generateProImports(componentInfo.name);

      const componentData: ComponentData = {
        name: componentInfo.name,
        category: componentInfo.category,
        title: title,
        description: description,
        documentation_url: this.normalizeUrl(componentInfo.url),
        api_reference: this.normalizeUrl(componentInfo.url + '#api'),
        version: '2.x',
        tags: this.generateProTags(componentInfo),
        props,
        examples,
        imports,
      };

      // 验证并修复数据完整性
      const validation = DataConverter.validateAndFixComponent(componentData);
      if (!validation.valid) {
        this.error(`Pro组件 ${componentInfo.name} 数据无效: ${validation.errors.join(', ')}`);
        return null;
      }

      // 使用修复后的数据
      const fixedComponentData = validation.fixedData;
      
      // 如果描述被修复了，记录日志
      if (componentData.description !== fixedComponentData.description) {
        this.log(`🔧 Pro组件 ${componentInfo.name} 描述已自动修复: "${fixedComponentData.description}"`);
      }

      return fixedComponentData;

    } catch (error) {
      this.error(`抓取Pro组件 ${componentInfo.name} 失败: ${error instanceof Error ? error.message : String(error)}`);
      return null;
    }
  }

  /**
   * 提取组件名称
   */
  private extractComponentName(url: string): string {
    const parts = url.split('/');
    const componentPath = parts[parts.length - 1];
    if (!componentPath) return '';
    
    // 转换为PascalCase
    return componentPath
      .split('-')
      .map(part => part.charAt(0).toUpperCase() + part.slice(1))
      .join('');
  }

  /**
   * 提取Pro组件标题
   */
  private extractTitle($: CheerioAPI): string {
    const selectors = [
      'h1',
      '.ant-typography h1',
      '[class*="title"]',
      '.markdown h1'
    ];

    for (const selector of selectors) {
      const title = $(selector).first().text();
      if (title) {
        const cleanTitle = this.cleanText(title);
        if (cleanTitle) {
          return cleanTitle.split(' ')[0] || '';
        }
      }
    }

    return '';
  }

  /**
   * 提取Pro组件描述
   */
  private extractDescription($: CheerioAPI): string {
    const selectors = [
      '.ant-typography p:first',
      '.markdown > p:first',
      'h1 + p',
      '.component-description'
    ];

    for (const selector of selectors) {
      const desc = $(selector).text();
      if (desc && desc.length > 10) {
        return this.cleanText(desc);
      }
    }

    return '';
  }

  /**
   * 提取Pro组件属性
   */
  private extractProProps($: CheerioAPI): Array<{ name: string; type: string; required: boolean; default_value?: string; description?: string }> {
    const props: Array<{ name: string; type: string; required: boolean; default_value?: string; description?: string }> = [];

    // 查找API表格
    $('table').each((_, table) => {
      const $table = $(table);
      const $headers = $table.find('thead th');
      
      // 检查是否是属性表格
      const headerTexts = $headers.map((_, th) => $(th).text().toLowerCase()).get();
      if (headerTexts.includes('参数') || headerTexts.includes('属性') || headerTexts.includes('property')) {
        
        $table.find('tbody tr').each((_, row) => {
          const $cells = $(row).find('td');
          if ($cells.length >= 3) {
            const name = this.cleanText($cells.eq(0).text());
            const description = this.cleanText($cells.eq(1).text());
            const type = this.cleanText($cells.eq(2).text());
            const defaultValue = $cells.length > 3 ? this.cleanText($cells.eq(3).text()) : undefined;

            if (name && type) {
              props.push({
                name,
                type: DataConverter.parseTypeDefinition(type),
                required: !defaultValue && !type.includes('?'),
                default_value: defaultValue !== '-' ? defaultValue : undefined,
                description: description !== '-' ? description : undefined,
              });
            }
          }
        });
      }
    });

    return props;
  }

  /**
   * 提取Pro组件代码示例
   */
  private extractProExamples($: CheerioAPI, componentName: string): Array<{ title: string; code: string; description?: string }> {
    const examples: Array<{ title: string; code: string; description?: string }> = [];

    // 查找代码块
    $('pre code, .ant-highlight pre').each((index, element) => {
      const $code = $(element);
      const code = $code.text();
      
      if (code && code.includes(componentName) && code.includes('import')) {
        const title = `示例 ${index + 1}`;
        const formattedCode = DataConverter.formatCode(code);
        
        if (formattedCode.length > 20) {
          examples.push({
            title,
            code: formattedCode,
            description: `${componentName} 使用示例`
          });
        }
      }
    });

    // 如果没有找到示例，生成基础示例
    if (examples.length === 0) {
      examples.push({
        title: '基础用法',
        code: this.generateProExample(componentName),
        description: `${componentName} 的基础使用示例`
      });
    }

    return examples.slice(0, 3);
  }

  /**
   * 生成Pro组件导入信息
   */
  private generateProImports(componentName: string): Array<{ import_path: string; import_name: string; is_default: boolean }> {
    const imports = [
      {
        import_path: '@ant-design/pro-components',
        import_name: componentName,
        is_default: false
      }
    ];

    // 某些组件可能还需要额外的导入
    if (componentName === 'ProLayout') {
      imports.push({
        import_path: '@ant-design/pro-layout',
        import_name: 'ProLayout',
        is_default: false
      });
    }

    return imports;
  }

  /**
   * 生成Pro组件标签
   */
  private generateProTags(componentInfo: { name: string; category: string }): string[] {
    const tags = new Set<string>();
    
    // 添加pro标签
    tags.add('pro');
    
    // 添加分类标签
    tags.add(componentInfo.category.toLowerCase());
    
    // 根据名称添加功能标签
    const name = componentInfo.name.toLowerCase();
    if (name.includes('form')) tags.add('form');
    if (name.includes('table')) tags.add('table');
    if (name.includes('layout')) tags.add('layout');
    if (name.includes('card')) tags.add('card');
    if (name.includes('list')) tags.add('list');
    if (name.includes('field')) tags.add('field');
    if (name.includes('descriptions')) tags.add('descriptions');
    
    return Array.from(tags);
  }

  /**
   * 获取默认描述
   */
  private getDefaultDescription(componentName: string): string {
    const descriptions: { [key: string]: string } = {
      'ProLayout': '高级布局组件，提供了标准的中后台布局，包含侧边栏、头部、面包屑等功能',
      'ProTable': '高级表格组件，在 Table 基础上增加了搜索、筛选、工具栏、分页等功能',
      'ProForm': '高级表单组件，提供了更简单的表单配置方式和丰富的表单项',
      'ProList': '高级列表组件，提供了卡片列表的标准布局',
      'ProCard': '高级卡片组件，提供了更丰富的卡片样式和功能',
      'ProDescriptions': '高级描述列表组件，提供了更灵活的描述列表配置',
      'ProField': '通用的数据渲染组件，可以根据数据类型自动选择合适的组件进行渲染',
      'BetaSchemaForm': '基于 Schema 的动态表单组件，支持通过配置快速生成表单',
    };

    return descriptions[componentName] || `${componentName} 是 Ant Design Pro 的高级组件`;
  }

  /**
   * 生成Pro组件示例代码
   */
  private generateProExample(componentName: string): string {
    const examples: { [key: string]: string } = {
      'ProLayout': `import { ProLayout } from '@ant-design/pro-components';

export default () => {
  return (
    <ProLayout
      title="Pro Layout"
      logo="https://gw.alipayobjects.com/zos/antfincdn/PmY%24TNNDBI/logo.svg"
      menuDataRender={() => [
        {
          path: '/dashboard',
          name: '仪表板',
          icon: 'dashboard',
        },
      ]}
    >
      <div>页面内容</div>
    </ProLayout>
  );
};`,

      'ProTable': `import { ProTable } from '@ant-design/pro-components';

export default () => {
  return (
    <ProTable
      columns={[
        {
          title: '姓名',
          dataIndex: 'name',
        },
        {
          title: '年龄',
          dataIndex: 'age',
        },
      ]}
      request={async () => ({
        data: [
          { key: '1', name: '张三', age: 28 },
          { key: '2', name: '李四', age: 32 },
        ],
        success: true,
        total: 2,
      })}
      rowKey="key"
      search={{
        labelWidth: 'auto',
      }}
    />
  );
};`,

      'ProForm': `import { ProForm, ProFormText } from '@ant-design/pro-components';

export default () => {
  return (
    <ProForm
      onFinish={async (values) => {
        console.log(values);
        return true;
      }}
    >
      <ProFormText
        name="name"
        label="姓名"
        rules={[{ required: true }]}
      />
      <ProFormText
        name="email"
        label="邮箱"
        rules={[{ required: true, type: 'email' }]}
      />
    </ProForm>
  );
};`,

      'ProCard': `import { ProCard } from '@ant-design/pro-components';

export default () => {
  return (
    <ProCard title="高级卡片" bordered>
      <div>卡片内容</div>
    </ProCard>
  );
};`,
    };

    return examples[componentName] || `import { ${componentName} } from '@ant-design/pro-components';

export default () => {
  return (
    <${componentName} />
  );
};`;
  }

  /**
   * 创建内置Pro组件
   */
  private createBuiltInProComponents(): ComponentData[] {
    const components: ComponentData[] = [];

    for (const [name, category] of this.proComponents) {
      const componentData: ComponentData = {
        name,
        category,
        title: name,
        description: this.getDefaultDescription(name),
        documentation_url: `https://procomponents.ant.design/components/${name.toLowerCase()}`,
        api_reference: `https://procomponents.ant.design/components/${name.toLowerCase()}#api`,
        version: '2.x',
        tags: this.generateProTags({ name, category }),
        props: this.getDefaultProps(name),
        examples: [{
          title: '基础用法',
          code: this.generateProExample(name),
          description: `${name} 的基础使用示例`
        }],
        imports: this.generateProImports(name),
      };

      components.push(componentData);
    }

    return components;
  }

  /**
   * 获取默认属性
   */
  private getDefaultProps(componentName: string): Array<{ name: string; type: string; required: boolean; default_value?: string; description?: string }> {
    const commonProps = [
      {
        name: 'className',
        type: 'string',
        required: false,
        description: '自定义样式类名'
      },
      {
        name: 'style',
        type: 'CSSProperties',
        required: false,
        description: '自定义样式'
      },
    ];

    const specificProps: { [key: string]: any[] } = {
      'ProTable': [
        ...commonProps,
        {
          name: 'columns',
          type: 'ProColumns[]',
          required: true,
          description: '表格列定义'
        },
        {
          name: 'request',
          type: 'function',
          required: false,
          description: '数据请求函数'
        },
        {
          name: 'rowKey',
          type: 'string | function',
          required: true,
          description: '行的唯一标识'
        },
      ],
      'ProForm': [
        ...commonProps,
        {
          name: 'onFinish',
          type: 'function',
          required: false,
          description: '表单提交回调'
        },
        {
          name: 'initialValues',
          type: 'object',
          required: false,
          description: '表单初始值'
        },
      ],
    };

    return specificProps[componentName] || commonProps;
  }
}